//
//  StatusViewModel.swift
//  weibo
//
//  Created by yellow on 15/10/19.
//  Copyright © 2015年 yellow. All rights reserved.
//

import UIKit
import SDWebImage

//微博视图模型，主要业务是获取网络数据
class StatusViewModel {
    
    //单例
    static var sharedViewModel = StatusViewModel()
    
    //懒加载微博集合
    var statusList:[StatusDetailViewModel] = [StatusDetailViewModel]()
    
    //网络数据接口
    private let weiboAPIManager = WeiboAPIManager.manager

}


// MARK: - 对上层控制器开放的接口
extension StatusViewModel{
    
    //获取当前登录用户及其所关注用户的最新微博,放在statusList中并执行闭包更新tableview
    func loadStatus(isPullUp isPullUp:Bool, finished:(isSuccess:Bool)->()){
        
        //构建获取最新微博的id,当第一次加载时就为0，
        let since_id = isPullUp ? 0: (self.statusList.first?.status.id ?? 0)
        
        //获取最尾部的微博id,为了分区这个2个参数，需要控制器传递参数来判断是上拉还是下拉
        let max_id = isPullUp ? (self.statusList.last?.status.id ?? 0) : 0
    
        
        StatusDAL.loadData(since_id, max_id: max_id) { (array) -> () in
            //临时数组，用来保存当次获取到的微博list
            var tempList = [StatusDetailViewModel]()
            guard let statusDictArray = array else{
                finished(isSuccess: false)
                return
            }
            for statusDict in statusDictArray {
                tempList.append(StatusDetailViewModel(status: Status(dict: statusDict)))
            }
            
            //让数组中最靠前的数据永远都是最新获取的微博
            
            //下拉追加到后面,否则追加到前面
            if max_id > 0 {
                self.statusList += tempList
            }else{
                self.statusList = tempList + self.statusList
            }
            
            
            //finished(isSuccess: true) 千万不能在这里完成回调，不然会出现发布微博(带图片的)cell高度获取的默认单图的pictureView的高度
            
            //缓存单张图片，以便获取大小, 然后再动态设置单张图片对应的itemSize大小
            self.cacheSingleImage(tempList,finished: finished)
        }
        
    }
    
    
    /// 传递微博viewModel数组，过滤出单张图片的url，并从服务器下载缓存到本地
    ///
    /// - parameter weiboList: 微博viewModel数组
    /// - parameter finished: 完成下载的回调，参数为bool
    private func cacheSingleImage(weiboList:[StatusDetailViewModel],finished:(isSuccess:Bool)->()){
        let group = dispatch_group_create()
        //记录图片长度
        var dataLength = 0
        
        for weibo in weiboList{
            //过滤掉非单张图片的微博
            if weibo.thumbnailUrls?.count != 1{
                continue
            }
            
            //处理单张图片
            let singleImgURL = weibo.thumbnailUrls![0]
            
            // 入组 - 监听后续的 block
            
            //定入组出组flage，让其出入组保持平衡
            var isCouple = false
            dispatch_group_enter(group)
            SDWebImageManager.sharedManager().downloadImageWithURL(singleImgURL, options: [SDWebImageOptions.RefreshCached,SDWebImageOptions.RetryFailed], progress: nil, completed: { (image, _, _, _, _) -> Void in
                
                //当SD下载失败后，重新执行该block时，就再次执行入组配对
                if isCouple == true {
                    self.doGroupEnterAndLeave(group, singleImgURL: singleImgURL, isCouple: isCouple, dataLength: dataLength)
                }else{
                    //下载完成单张图片，并计算长度（UIImagePNGRepresentation是通过图片返回png格式的二进制内容）
                    if let img = image,let data = UIImagePNGRepresentation(img) {
                        dataLength += data.length
                    }
                    
                    dispatch_group_leave(group)//出组
                    isCouple = true
                }
            })
        }
        
        // 3. 监听调度组完成
        dispatch_group_notify(group, dispatch_get_main_queue(), { () -> Void in
            print("缓存图片完成，总大小:\(dataLength/1024)KB")
            finished(isSuccess: true)
        })
    }
    
    
/// 递归 执行入组出组block,如果下载失败，就会执行SD中的闭包，进行判断如果不是成对的重新执行enter block leave
    private func doGroupEnterAndLeave(group:dispatch_group_t,singleImgURL:NSURL,var isCouple:Bool,var dataLength:Int){
        isCouple = false
        dispatch_group_enter(group)
        SDWebImageManager.sharedManager().downloadImageWithURL(singleImgURL, options: [SDWebImageOptions.RefreshCached,SDWebImageOptions.RetryFailed], progress: nil, completed: { (image, _, _, _, _) -> Void in
            
            //当SD下载失败后，重新执行该block时，就再次执行入组配对
            if isCouple == true {
                self.doGroupEnterAndLeave(group, singleImgURL: singleImgURL, isCouple: isCouple, dataLength: dataLength)
            }else{
                //下载完成单张图片，并计算长度（UIImagePNGRepresentation是通过图片返回png格式的二进制内容）
                if let img = image,let data = UIImagePNGRepresentation(img) {
                    dataLength += data.length
                }
                
                dispatch_group_leave(group)//出组
                isCouple = true
            }
        })
    }
}
